#include<iostream>
#include<time.h>
#include<assert.h>
#include"Socket.hpp"
#include"protocol.hpp"

// ./clientcal ip port
static void Usage(const std::string &proc)
{
    std::cout << "\nUsage: " << proc << " serverip serverport\n" << std::endl;
} 


int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(-1);
    }
    uint16_t serverport = std::stoi(argv[2]);
    std::string serverip = argv[1];

    Sock sockfd;
    //创建套接字
    sockfd.Socket();  
    bool r = sockfd.Connect(serverip, serverport);
    if(!r) return 1;
    
    srand(time(nullptr) ^ getpid());
    int cnt = 1;
    const std::string opers = "+-*/%";

    std::string inbuffer_stream;
    while(cnt <= 10)
    {
        std::cout << "=====================第" << cnt << "次测试...."<< "=====================" << std::endl;
        int x = rand() % 100 + 1;
        usleep(1234);
        int y = rand() % 100 + 1;
        usleep(4321);
        char oper = opers[rand() % opers.size()];

        Request req(x, y, oper);//构造一个结构化的数据
        req.DebugPrint();//请求构建完成

        // 序列化
        std::string content;
        req.Serialize(content);

        //封装报头
        std::string package = Encode(content);

        write(sockfd.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新发出的请求： \n" << package;

        // write(sockfd.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新发出的请求： \n" << package;

        // write(sockfd.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新发出的请求： \n" << package;

        // write(sockfd.Fd(), package.c_str(), package.size());
        // std::cout << "这是最新发出的请求： \n" << package;

       
        
        char buffer[128];
        // 我们也无法保证能读取到一个完整的报文
        ssize_t n = read(sockfd.Fd(), buffer, sizeof(buffer));
        if(n > 0)
        {
            buffer[n] = 0;
            inbuffer_stream += buffer;//"len"\n"result code"\n"
            //提取有效载荷
            std::string content;
            bool r = Decode(inbuffer_stream, content); //"result code"
            assert(r);

            //反序列化 --转化为结构数据类型
            Response resp;
            r = resp.Desrialize(content);
            assert(r);

            resp.DebugPrint();
        }
        std::cout << "=======================================================" << std::endl;
        sleep(1);
        cnt++;
    }

    
    sockfd.Close();
    return 0;
}

